package com.mygame.game_server;

import com.google.protobuf.GeneratedMessageV3;
import com.mygame.game_server.msgcoder.GameMsgRecognizer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;



/**
 * @author Jim
 * @date 00:02 2022/5/6
 * @description 编码器
 * @email:huwmz04153277@126.com
 */
public class GameMessageEncoder extends ChannelOutboundHandlerAdapter {


    /**
     * 日志对象
     */
    static private final Logger LOGGER = LoggerFactory.getLogger(GameMessageEncoder.class);

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {

        if (null == ctx ||
                null == msg) {
            return;
        }

        try {
            if (!(msg instanceof GeneratedMessageV3)) {
                super.write(ctx, msg, promise);
                return;
            }

            // 消息编码
            int msgCode = GameMsgRecognizer.getMessageCode(cast(msg).getClass());

            if (-1 == msgCode) {
                LOGGER.error(
                        "无法识别的消息类型, msgClazz = {}",
                        msg.getClass().getSimpleName()
                );
                super.write(ctx, msg, promise);
                return;
            }
//            if (msg instanceof GameMsgProtocol.UserEntryResult) {
//                msgCode = GameMsgProtocol.MsgCode.USER_ENTRY_RESULT_VALUE;
//            } else if (msg instanceof GameMsgProtocol.WhoElseIsHereResult) {
//                msgCode = GameMsgProtocol.MsgCode.WHO_ELSE_IS_HERE_RESULT_VALUE;
//            } else if (msg instanceof GameMsgProtocol.UserMoveToResult) {
//                msgCode = GameMsgProtocol.MsgCode.USER_MOVE_TO_RESULT_VALUE;
//            } else if (msg instanceof GameMsgProtocol.UserQuitResult){
//                msgCode = GameMsgProtocol.MsgCode.USER_QUIT_RESULT_VALUE;
//            } else {
//                LOGGER.error(
//                        "无法识别的消息类型, msgClazz = {}",
//                        msg.getClass().getSimpleName()
//                );
//                super.write(ctx, msg, promise);
//                return;
//            }

            // 消息体
            byte[] msgBody = ((GeneratedMessageV3) msg).toByteArray();

            ByteBuf byteBuf = ctx.alloc().buffer();
            byteBuf.writeShort((short) msgBody.length); // 消息的长度
            byteBuf.writeShort((short) msgCode); // 消息编号
            byteBuf.writeBytes(msgBody); // 消息体

            // 写出 ByteBuf
            BinaryWebSocketFrame outputFrame = new BinaryWebSocketFrame(byteBuf);
            //将数据刷入ChannelOutboundBuffer
            super.write(ctx, outputFrame, promise);
        } catch (Exception ex) {
            // 记录错误日志
            LOGGER.error(ex.getMessage(), ex);
        }
    }

    private static <T extends GeneratedMessageV3> T cast(Object msg) {
        if (null == msg) {
            return null;
        }
        return (T) msg;
    }
}
